package com.brillilab.service.core.experiments.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.dao.mapper.experiments.ExperimentStepTimerMapper;
import com.brillilab.domain.po.experiments.ExperimentStepTimer;
import com.brillilab.service.core.experiments.IExperimentStepTimerService;
import com.brillilab.service.quartz.BrillQuartzScheduler;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class ExperimentStepTimerServiceImpl implements IExperimentStepTimerService {

    @Resource
    private ExperimentStepTimerMapper experimentStepTimerMapper;
    @Resource
    private BrillQuartzScheduler scheduler;

    @Override
    public boolean endTimerById(Long id) {
        return experimentStepTimerMapper.setStateToEndById(id) >0;
    }

    @Override
    public boolean insert(ExperimentStepTimer timer) {
        return experimentStepTimerMapper.insert(timer) > 0;
    }

    @Override
    public boolean updateById(ExperimentStepTimer timer) {
        return experimentStepTimerMapper.updateById(timer) > 0;
    }

    @Override
    public List<ExperimentStepTimer> selectList(Long experimentId,Long phaseId,Long stepId) {

        LambdaQueryWrapper<ExperimentStepTimer> wrapper=new LambdaQueryWrapper<ExperimentStepTimer>()
                .eq(ExperimentStepTimer::getExperimentId,experimentId);
        if(phaseId!=null){
            wrapper.eq(ExperimentStepTimer::getPhaseId,phaseId);
        }
        if(stepId!=null){
            wrapper.eq(ExperimentStepTimer::getStepId,stepId);
        }
        return experimentStepTimerMapper.selectList(wrapper);
    }

    @Override
    public ExperimentStepTimer selectById(Long timerId) {
        return experimentStepTimerMapper.selectById(timerId);
    }

    @Override
    public boolean updateBatch(List<ExperimentStepTimer> timers) {
        if(timers!=null && timers.size()>0){
            return experimentStepTimerMapper.updateBatch(timers) > 0;
        }
        return true;
    }

    @Override
    public void deleteById(Long timerId){
        int i=experimentStepTimerMapper.deleteById(timerId);
        Assert.isTrue(i==1,"操作失败！");
    }

    @Override
    public boolean insertBatch(List<ExperimentStepTimer> stepTimersToInsert) {
        if(CollectionUtils.isNotEmpty(stepTimersToInsert)){
            return experimentStepTimerMapper.insertBatch(stepTimersToInsert) > 0;
        }
        return true;
    }

	@Override
	public List<ExperimentStepTimer> selectStepTimerList(Long experimentId) {
		 return experimentStepTimerMapper.selectList(
	                new LambdaQueryWrapper<ExperimentStepTimer>()
	                        .eq(ExperimentStepTimer::getExperimentId,experimentId));
	}

    @Override
    public boolean deleteByExperimentId(Long experimentId) {
        return experimentStepTimerMapper.delete(
                new LambdaQueryWrapper<ExperimentStepTimer>()
                        .eq(ExperimentStepTimer::getExperimentId,experimentId))>0;
    }

    @Override
    public void endTimersByExperimentId(Long experimentId) {
        List<ExperimentStepTimer> timers=experimentStepTimerMapper.selectList(
                new LambdaQueryWrapper<ExperimentStepTimer>()
                        .eq(ExperimentStepTimer::getExperimentId,experimentId));
        if(CollectionUtils.isNotEmpty(timers)){
            //删除定时任务
            Map<String, String> groupAndName =
                    timers.stream().filter(e -> !StringUtils.isEmpty(e.getJobGroup()) && !StringUtils.isEmpty(e.getJobName())).collect(
                            Collectors.toMap(ExperimentStepTimer::getJobName,ExperimentStepTimer::getJobGroup));

            groupAndName.forEach((k,v) ->{
                scheduler.deleteJob(k,v);
            });
            //更新计时器状态
            List<Long> timerIds=timers.stream().map(ExperimentStepTimer::getId).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(timerIds)){
                experimentStepTimerMapper.setStateToEndByIds(timerIds);
            }
        }
    }
}
